#include "clayout.h"

/**
 * CLayout - constructor, initialization
 */
CLayout::CLayout() {
  clear();
  patternSizesX.push_back(50);
  patternSizesY.push_back(50);
  paddingX = 0;
  paddingY = 0;
  spacingX = 0;
  spacingY = 0;
}
//---------------------------------------------------------------------------

/**
 * CLayout - constructor, initialization with lists of cell dimensions
 * @param patternSizesX
 * @param patternSizesY
 * @param paddingX
 * @param paddingY
 * @param spacingX
 * @param spacingY
 */
CLayout::CLayout(const vector<unsigned short> &patternSizesX,
    const vector<unsigned short> &patternSizesY, unsigned short paddingX,
    unsigned short paddingY, unsigned short spacingX, unsigned short spacingY) {
  clear();
  this->patternSizesX = patternSizesX;
  this->patternSizesY = patternSizesY;
  this->paddingX = paddingX;
  this->paddingY = paddingY;
  this->spacingX = spacingX;
  this->spacingY = spacingY;
}
//---------------------------------------------------------------------------

/**
 * CLayout - consturctor, initialization with strings with cell dimensions
 * @param patternSizesX
 * @param patternSizesY
 * @param paddingX
 * @param paddingY
 * @param spacingX
 * @param spacingY
 */
CLayout::CLayout(string patternSizesX, string patternSizesY,
    unsigned short paddingX, unsigned short paddingY,
    unsigned short spacingX, unsigned short spacingY) {
  clear();
  createPatternSizesFromString(patternSizesX, this->patternSizesX);
  createPatternSizesFromString(patternSizesY, this->patternSizesY);
  this->paddingX = paddingX;
  this->paddingY = paddingY;
  this->spacingX = spacingX;
  this->spacingY = spacingY;
}
//---------------------------------------------------------------------------

/**
 * createPatternSizesFromString - creates pattern from string with numbers
 * @param str
 * @param v
 */
void CLayout::createPatternSizesFromString(string str,
    vector<unsigned short> &v) {
  CStringUtils::replaceAll(" ", "", str);
  vector<string> tmp = CStringUtils::explode(",", str);
  for (vector<string>::iterator i = tmp.begin(); i < tmp.end(); i++) {
    v.push_back(CMath<unsigned short>::parse(*i));
  }
}
//---------------------------------------------------------------------------

/**
 * sumPatternSizes - sums numbers in given scope of pattern
 * @param v
 * @param begin
 * @param end
 * @return sum of heights/widths
 */
unsigned short CLayout::sumPatternSizes(vector<unsigned short> &v,
    TIndex begin, TIndex end) {
  unsigned short sum(0);
  vector<unsigned short>::iterator i = v.begin() + begin;
  for (; i < v.begin() + end; i++) {
    sum += (*i);
  }
  return sum;
}
//---------------------------------------------------------------------------

/**
 * getPaddingX - returns padding on x axis
 * @return x axis padding
 */
unsigned short CLayout::getPaddingX() const {
  return paddingX;
}
//---------------------------------------------------------------------------

/**
 * getPaddingY - returns padding on y axis
 * @return y axis padding
 */
unsigned short CLayout::getPaddingY() const {
  return paddingY;
}
//---------------------------------------------------------------------------

/**
 * getSpacingX - returns spacing between cells on x axis
 * @return x axis spacing
 */
unsigned short CLayout::getSpacingX() const {
  return spacingX;
}
//---------------------------------------------------------------------------

/**
 * getSpacingY - returns spacing between cells on y axis
 * @return y axis spacing
 */
unsigned short CLayout::getSpacingY() const {
  return spacingY;
}
//---------------------------------------------------------------------------

/**
 * calculateTotalWidth - calculates and returns total width of layout
 * @return layout width
 */
unsigned short CLayout::calculateTotalWidth() {
  return (paddingX << 1) + (patternSizesX.size() - 1) * spacingX
      + sumPatternSizes(patternSizesX, 0, patternSizesX.size());
}
//---------------------------------------------------------------------------

/**
 * calculateTotalHeight - calculates and returns total height of layout
 * @return layout height
 */
unsigned short CLayout::calculateTotalHeight() {
  return (paddingY << 1) + (patternSizesY.size() - 1) * spacingY
      + sumPatternSizes(patternSizesY, 0, patternSizesY.size());
}
//---------------------------------------------------------------------------

/**
 * calculateComponentCoordX - returns x axis position of given component
 * @param posX component index in layout
 * @return relative x position of component vs layout owner
 */
unsigned short CLayout::calculateComponentCoordX(TIndex posX) {
  return paddingX + posX * spacingX + sumPatternSizes(patternSizesX, 0, posX);
}
//---------------------------------------------------------------------------

/**
 * calculateComponentCoordY - returns x axis position of given component
 * @param posY component index in layout
 * @return relative y position of component vs layout owner
 */
unsigned short CLayout::calculateComponentCoordY(TIndex posY) {
  return paddingY + posY * spacingY + sumPatternSizes(patternSizesY, 0, posY);
}
//---------------------------------------------------------------------------

/**
 * calculateComponentWidth - returns width of component on given index
 * @param posX
 * @param spanX
 * @return component width
 */
unsigned short CLayout::calculateComponentWidth(TIndex posX, TIndex spanX) {
  return (spanX - 1) * spacingX + sumPatternSizes(patternSizesX, posX, posX
      + spanX);
}
//---------------------------------------------------------------------------

/**
 * calculateComponentHeight - returns height of component on given index
 * @param posY
 * @param spanY
 * @return component height
 */
unsigned short CLayout::calculateComponentHeight(TIndex posY, TIndex spanY) {
  return (spanY - 1) * spacingY + sumPatternSizes(patternSizesY, posY, posY
      + spanY);
}
//---------------------------------------------------------------------------

/**
 * clear - clears lists of component dimensions
 */
void CLayout::clear() {
  if (patternSizesX.size() > 0) {
    patternSizesX.clear();
  }
  if (patternSizesY.size() > 0) {
    patternSizesY.clear();
  }
}
//---------------------------------------------------------------------------
